package com.ling.travels.controller;

import com.ling.travels.pojo.Result;
import com.ling.travels.pojo.User;
import com.ling.travels.service.UserService;
import com.ling.travels.utils.VerifyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@RestController     // 返回字符串，走解析器，找不到ok页面 ,可以用RestController
@CrossOrigin   // 允许跨域
@Slf4j
public class UserController {

    //获得验证码
    @RequestMapping("/getCode")
    public Map<String,String> getCode(HttpServletRequest request) throws IOException {
        Map<String, String> result = new HashMap<>();
        //1.获取验证码对象(包括image和code)
        Map<String, Object> map = VerifyUtil.createImage();
        //2.取出code对象，并转化为String类型
        String code = (String) map.get("code");
        //3.将code存入session中
        //生成一个时间戳
        String key = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        request.getServletContext().setAttribute(key,code);
        //session.setAttribute("VCode",code);
        //4.取出验证码背景图片
        BufferedImage image = (BufferedImage) map.get("image");

        //5.响应给浏览器  ImageIO ：工具类

        //获取流之前最好设置一下响应类型，如这里的"image/png"，也可以不设置，但为了规范以后自己一定都要设置一下
        //response.setContentType("image/png");

        //进行base64编码
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //传入image验证码背景图片，格式为png，通过 response.getOutputStream() 响应出去，这里会抛出一个IO异常
        //ImageIO.write(image,"png",response.getOutputStream());
        ImageIO.write(image,"png",bos);
        String s = Base64Utils.encodeToString(bos.toByteArray());
        result.put("key",key);
        result.put("image",s);
        return result;
    }

    @Autowired
    private UserService userService;

    // 注册实现
    @PostMapping("/register")
    public Result register(String code, String key, @RequestBody User user, HttpServletRequest request){
        Result result = new Result();
        log.info("接收前端的验证码："+code);
        log.info("接收前端的user对象："+user);
        // 取出session中的验证码
        String keyCode = (String) request.getServletContext().getAttribute(key);
        try {
            // 验证验证码
            if (code.equalsIgnoreCase(keyCode)){
                // 注册
                userService.register(user);
                result.setMsg("注册成功！");
            }else {
                throw new RuntimeException("验证码错误！");
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setMsg(e.getMessage()).setState(false);
        }
        return result;
    }

    //登录，这里不加 @RequestBody 接收不到前端传来的数据
    @RequestMapping("/login")
    public Result login(@RequestBody User user,HttpServletRequest request){
        log.info("user；"+user);
        Result result = new Result();

        // controller只是调用service层，传递相应的参数，拿到对应的数据；具体的业务已在service层实现了
        // 调用service层的login方法，拿到service层返回的一个用户信息
        User userDB = userService.login(user);
        if (userDB!=null){
            /** 登录成功之后应保存用户的标记，
             * 在前后端分离的项目中session无效，可保存在全局的ServletContext中，但这种方式非常占用服务器资源
             * 实际开发中 一般用 Redis (userid,userdb) 来保存
             * 这里暂时保存在ServletContext中,即这里的 HttpServletRequest request 参数
             */
            request.getServletContext().setAttribute(userDB.getId(),userDB);
            result.setMsg("登录成功~~~").setUserId(userDB.getId());
        }else {
            result.setState(false);
        }

        return result;
    }


}














